package com.xtedu.examproject.util;

import cn.hutool.json.JSONObject;
import com.fatboyindustrial.gsonjavatime.Converters;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.Map;

import org.apache.poi.ss.usermodel.*;
import redis.clients.jedis.Jedis;



public class CommonUtils {
    // 响应状态码常量
    private static final int CODE_SUCCESS = 1;
    private static final int CODE_FAILURE = 0;

    // 响应json工具方法========
    public static void sendSuccessResponse(HttpServletResponse response, String message, Object data) throws IOException {
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("code", CODE_SUCCESS);
        responseData.put("message", message);
        responseData.put("data", data);
        Gson gson = createGson();
        String responseJson = gson.toJson(responseData);
        response.getWriter().write(responseJson);
    }

    public static void sendSuccessResponse(HttpServletResponse response, String message) throws IOException {
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("code", CODE_SUCCESS);
        responseData.put("message", message);
        Gson gson = createGson();
        String responseJson = gson.toJson(responseData);
        response.getWriter().write(responseJson);
    }

    public static void sendErrorResponse(HttpServletResponse response, String message) throws IOException {
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("code", CODE_FAILURE);
        responseData.put("message", message);
        Gson gson = createGson();
        String responseJson = gson.toJson(responseData);
        // ObjectMapper objectMapper = createObjectMapper();
        // String responseJson = objectMapper.writeValueAsString(responseData);
        response.getWriter().write(responseJson);
    }

    /**
     * 创建Gson对象
     *
     * @return Gson对象
     */
    public static Gson createGson() {
        return Converters.registerAll(new GsonBuilder()).create();
    }

    // json数据格式处理方法========
    public static String getJsonFromRequest(HttpServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = request.getReader();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }

    public static <T> T getJsonFromRequest(HttpServletRequest request, Class<T> clazz) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = request.getReader();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }

        Gson gson = createGson();
        return gson.fromJson(sb.toString(), clazz);
        // // 如果使用Jackson库
        // ObjectMapper objectMapper = createObjectMapper();
        // return objectMapper.readValue(sb.toString(), clazz);
    }

    /**
     * 从表单fromData数据中获取数据,封装为对象返回
     *
     * @param request 请求对象
     * @param clazz   对象类型
     * @param <T>     泛型
     * @return 对象
     * @throws IOException 抛出IO异常
     */
    public static <T> T getFormDataFromRequest(HttpServletRequest request, Class<T> clazz) throws IOException {
        try {
            // 创建类的实例
            T instance = clazz.getDeclaredConstructor().newInstance();

            // 通过反射获取实体类字段
            Field[] fields = clazz.getDeclaredFields();

            // 遍历字段，将表单数据设置给实例对象的字段
            for (Field field : fields) {
                field.setAccessible(true);
                String parameterValue = request.getParameter(field.getName());

                if (parameterValue != null) {
                    // 根据字段类型进行适当的类型转换
                    Object convertedValue = convertParameterValue(parameterValue, field.getType());
                    field.set(instance, convertedValue);
                } else {
                    // 如果字段值为空，则将字段设置为null,字段额外校验需自行设置
                    field.set(instance, null);
                }
            }
            return instance;
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
                 NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将字符串参数值转换为指定类型
     *
     * @param value      字符串值
     * @param targetType 目标类型
     * @return 转换后的值
     */
    private static Object convertParameterValue(String value, Class<?> targetType) {
        if (targetType == String.class) {
            return value;
        } else if (targetType == int.class || targetType == Integer.class) {
            return Integer.parseInt(value);
        } else if (targetType == long.class || targetType == Long.class) {
            return Long.parseLong(value);
        } else if (targetType == boolean.class || targetType == Boolean.class) {
            return Boolean.parseBoolean(value);
        } else if (targetType == double.class || targetType == Double.class) {
            return Double.parseDouble(value);
        } else if (targetType == Timestamp.class) {
            return parseTimestamp(value);
        } else if (targetType == LocalDateTime.class) {
            return parseLocalDateTime(value);
        }
        // 可以根据需要添加更多类型转换

        // 默认返回原字符串
        return value;
    }

    /**
     * 解析时间戳字符串为 Timestamp 对象
     *
     * @param value 时间字符串
     * @return Timestamp 对象
     */
    private static Timestamp parseTimestamp(String value) {
        // 支持多种时间格式
        String[] patterns = {
                "yyyy-MM-dd HH:mm:ss",  // 完整时间格式
                "yyyy-MM-dd HH:mm",     // 到分钟
                "yyyy-MM-dd",           // 只有日期
                "yyyy/MM/dd HH:mm:ss",  // 斜杠分隔符
                "yyyy/MM/dd"            // 斜杠分隔符只有日期
        };

        for (String pattern : patterns) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                sdf.setLenient(false); // 严格模式
                Date date = sdf.parse(value);
                return new Timestamp(date.getTime());
            } catch (ParseException ignored) {
                // 继续尝试下一个格式
            }
        }

        // 如果所有格式都失败，抛出异常
        throw new RuntimeException("无法解析时间格式: " + value);
    }

    /**
     * 解析时间字符串为 LocalDateTime 对象
     *
     * @param value 时间字符串
     * @return LocalDateTime 对象
     */
    private static LocalDateTime parseLocalDateTime(String value) {
        // 支持多种时间格式
        String[] patterns = {
                "yyyy-MM-dd HH:mm:ss",
                "yyyy-MM-dd HH:mm",
                "yyyy-MM-dd"
        };

        for (String pattern : patterns) {
            try {
                return LocalDateTime.parse(value,
                        java.time.format.DateTimeFormatter.ofPattern(pattern));
            } catch (java.time.format.DateTimeParseException ignored) {
                // 继续尝试下一个格式
            }
        }

        // 如果所有格式都失败，抛出异常
        throw new RuntimeException("无法解析时间格式: " + value);
    }


    public static void jsonToRedisHash(String redisKey, String jsonString) {
        try (Jedis jedis = new Jedis("localhost", 6379)) {
            Gson gson = new Gson();
            Type type = new TypeToken<Map<String, Object>>() {}.getType();
            Map<String, Object> map = gson.fromJson(jsonString, type);

            for (Map.Entry<String, Object> entry : map.entrySet()) {
                jedis.hset(redisKey, entry.getKey(), String.valueOf(entry.getValue())); // redisKey：Redis 中的 Hash 键名，比如 "user:123"
            }
        }
    }

}